package turtle.system.invest.rule;

import org.osite.xml.XmlConstructor;
import org.osite.xml.XmlParam;

import turtle.system.invest.BarType;
import turtle.system.invest.Environment;

public class WinnieRule extends AbstractRule {

    private int daysInForShort;
    private int daysInForLong;
    private int daysOutForShort;
    private int daysOutForLong;
    private int forceStopLoss;
    
    @XmlConstructor
    public WinnieRule(
    		@XmlParam("daysInForShort") int daysInForShort, 
    		@XmlParam("daysInForLong") int daysInForLong, 
    		@XmlParam("daysOutForShort") int daysOutForShort, 
    		@XmlParam("daysOutForLong") int daysOutForLong, 
    		@XmlParam("forceStopLoss") int forceStopLoss) {
    	this.daysInForShort = daysInForShort;
    	this.daysInForLong = daysInForLong;
    	this.daysOutForShort = daysOutForShort;
    	this.daysOutForLong = daysOutForLong;
    	this.forceStopLoss = forceStopLoss;
    }
    
    public String toString() {
    	StringBuilder sb = new StringBuilder("WinneRule");
    	sb.append("(").append(daysInForShort);
    	sb.append(", ").append(daysInForLong);
    	sb.append(", ").append(daysOutForShort);
    	sb.append(", ").append(daysOutForLong);
    	sb.append(", ").append(forceStopLoss).append(')');
    	return sb.toString();
    }

    @Override
    public void setup(Environment env) {
        super.setup(env);
        super.setStopLoss(forceStopLoss);
    }

    protected void doPlanning(Environment env, int timestamp) {
        InvestHistory history = env.getInvestHistory();
        wtx1.setTimestamp(timestamp);
        wtx0.setTimestamp(timestamp);

        int hold = history.getHoldPosition();

        if (hold == 0) {
            boolean bMax = wtx0.isBreakMaximum(BarType.HIGH, daysInForLong);
            boolean bMin = wtx0.isBreakMinimum(BarType.LOW, daysInForShort);
            if (!bMax && bMin) adjustAtOpen(1);
            if (bMax && !bMin) adjustAtOpen(-1); 
        } else if (hold > 0) {
            if (wtx0.isBreakMinimum(BarType.HIGH, daysOutForLong)
                    && wtx0.isBreakMinimum(BarType.LOW, daysOutForLong)
                    && wtx0.isBreakMinimum(BarType.CLOSE, daysOutForLong)) {
                if (history.getProfit(wtx1.get(BarType.CLOSE)) > 0) {
                    adjustAtOpen(-1);
                } else {
                    adjustAtClose(-1);
                }
            }
        } else if (hold < 0) {
            if (wtx0.isBreakMaximum(BarType.HIGH, daysOutForShort)
                    && wtx0.isBreakMaximum(BarType.LOW, daysOutForShort)
                    && wtx0.isBreakMaximum(BarType.CLOSE, daysOutForShort)) {
                adjustAtOpen(1);
            }
        }
    }

}
